﻿using System;
using System.Web.UI;
using ChannelVN.CMS.Common;
using ChannelVN.CMS.DynamicLayout.Entity;
using ChannelVN.CMS.DynamicLayout.FrontEnd.Common;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.Caching;
using ChannelVN.CMS.DynamicLayout.FrontEnd.Bo;

namespace ChannelVN.CMS.DynamicLayout.FrontEnd.Base
{
    public abstract class DynamicPageBase : Page
    {
        protected bool IsDesignMode
        {
            get { return PostDataFromAdmin.SecretKey == ConfigValues.DynamicLayoutSecretKey && PostDataFromAdmin.IsLoadPageAction; }
        }

        protected PageWithFullModuleEntity PageInfo { get; set; }

        private const string PageConfigCacheKey = "DynamicLayout.PageConfig";

        protected void OnPreLoadDynamicPage()
        {
            if (!IsPostBack)
            {
                if (PostDataFromAdmin.SecretKey == ConfigValues.DynamicLayoutSecretKey)
                {
                    if (PostDataFromAdmin.IsLoadPageAction)
                    {
                        #region Load page content
                        var jsonPageDetail = PostDataFromAdmin.PageDetail;
                        PageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(jsonPageDetail);

                        //WebHelpers.AddBaseMetaTag(this, ConfigValues.HostUrl);

                        if (Master != null)
                        {
                            LoadControlIntoPlaceHolderInAdminMode(Page.Master, PageInfo.ListModuleInPage);
                        }
                        else
                        {
                            LoadControlIntoPlaceHolderInAdminMode(Page, PageInfo.ListModuleInPage);
                        }
                        #endregion
                    }
                    else if (PostDataFromAdmin.IsPreviewAction)
                    {
                        #region Load page content
                        var jsonPageDetail = PostDataFromAdmin.PageDetail;
                        PageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(jsonPageDetail);

                        //WebHelpers.AddBaseMetaTag(this, ConfigValues.HostUrl);

                        if (Master != null)
                        {
                            LoadControlIntoPlaceHolderInFrontEndMode(Page.Master, PageInfo.ListModuleInPage);
                        }
                        else
                        {
                            LoadControlIntoPlaceHolderInFrontEndMode(Page, PageInfo.ListModuleInPage);
                        }
                        #endregion
                    }
                    else if (PostDataFromAdmin.IsPublishPageAction)
                    {
                        #region Publish page configuration into file and iis cache
                        var jsonPageDetail = PostDataFromAdmin.PageDetail;
                        PageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(jsonPageDetail);

                        SavePageConfig(PageInfo, jsonPageDetail);

                        Response.Write("1");
                        Response.End();
                        #endregion
                    }
                }
                else
                {
                    PageInfo = GetPageConfigForFrontEnd();

                    if (null != PageInfo)
                    {
                        if (Master != null)
                        {
                            LoadControlIntoPlaceHolderInFrontEndMode(Page.Master, PageInfo.ListModuleInPage);
                        }
                        else
                        {
                            LoadControlIntoPlaceHolderInFrontEndMode(Page, PageInfo.ListModuleInPage);
                        }
                    }
                }
            }
        }

        private void SavePageConfig(PageWithFullModuleEntity pageConfigObject, string pageConfigInJson)
        {
            // Save into iis cache
            HttpContext.Current.Cache.Remove(PageConfigCacheKey);
            HttpContext.Current.Cache.Add(PageConfigCacheKey, pageConfigObject, null,
                                          DateTime.Now.AddDays(10), TimeSpan.Zero, CacheItemPriority.High,
                                          null);
            // Save into file
            string url = Request.FilePath;
            url = url.Substring(url.LastIndexOf("/") + 1);
            string configFilePath = ConfigValues.PageConfigCachingFolder + url + ".config";

            using (var writer = File.CreateText(configFilePath))
            {
                writer.Write(pageConfigInJson);
                writer.Close();
            }
        }

        private PageWithFullModuleEntity GetPageConfigForFrontEnd()
        {
            PageWithFullModuleEntity pageInfo = null;

            #region Get page config in file

            if (ConfigValues.IsGetDefaultPageConfig)
            {
                var url = Request.FilePath;
                url = url.Substring(url.LastIndexOf("/") + 1);
                var configFilePath = ConfigValues.PageConfigCachingFolder + url + ".config";

                if (File.Exists(configFilePath))
                {
                    using (var reader = File.OpenText(configFilePath))
                    {
                        var json = reader.ReadToEnd();
                        pageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(json);
                    }
                }
            }

            #endregion

            #region Get page config in cache first

            //if (null == pageInfo)
            //{
            //    pageInfo = HttpContext.Current.Cache[PageConfigCacheKey] as PageWithFullModuleEntity;
            //}

            #endregion

            #region get page config from database

            if (null == pageInfo)
            {
                var pageConfig = NewsConfigBo.GetByConfigName(ConfigValues.NewsConfigNameForDynamicLayout);
                if (!string.IsNullOrEmpty(pageConfig))
                {
                    pageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(pageConfig);
                    // save config
                    SavePageConfig(pageInfo, pageConfig);
                }
            }

            #endregion

            #region get page config from admin server

            //if (null == pageInfo)
            //{
            //    try
            //    {
            //        var adminUrl = ConfigValues.DynamicLayoutUrl + "GetPageConfiguration.ashx";

            //        var responseText = string.Empty;

            //        var parameters = "secretKey=" + ConfigValues.DynamicLayoutSecretKey + "&pageSrc=" + Request.FilePath;

            //        var httpRequest = (HttpWebRequest)WebRequest.Create(adminUrl + "?" + parameters);
            //        httpRequest.Method = "GET";
            //        httpRequest.KeepAlive = true;
            //        httpRequest.MaximumResponseHeadersLength = int.MaxValue;

            //        var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            //        var responseStream = httpResponse.GetResponseStream();
            //        if (null != responseStream)
            //        {
            //            using (var streamReader = new StreamReader(responseStream))
            //            {
            //                responseText = streamReader.ReadToEnd();
            //                streamReader.Close();
            //            }
            //            responseStream.Close();
            //        }
            //        httpResponse.Close();

            //        pageInfo = NewtonJson.Deserialize<PageWithFullModuleEntity>(responseText);

            //        // save config
            //        SavePageConfig(pageInfo, responseText);
            //    }
            //    catch (Exception)
            //    {

            //    }
            //}

            #endregion

            return pageInfo;
        }

        private const string PlaceHolderCssClassName = "DLModulePlaceHolder";

        private void LoadControlIntoPlaceHolderInAdminMode(Control currentSearchControl, List<FullModuleInPageWithConfigEntity> listModuleInPage)
        {
            foreach (Control pageControl in currentSearchControl.Controls)
            {
                if (pageControl is HtmlGenericControl)
                {
                    var placeHolder = pageControl as HtmlGenericControl;
                    var placeHolderName = placeHolder.Attributes["placeholdername"];
                    if (!string.IsNullOrEmpty(placeHolderName))
                    {
                        var placeHolderClassName = placeHolder.Attributes["class"];
                        placeHolderClassName = placeHolderClassName + " " + PlaceHolderCssClassName;
                        placeHolder.Attributes["class"] = placeHolderClassName;

                        foreach (var moduleInPage in listModuleInPage)
                        {
                            if (!placeHolderName.Equals(moduleInPage.PlaceHolderName, StringComparison.CurrentCultureIgnoreCase)) continue;

                            var control = LoadControl(moduleInPage.SkinSrc);
                            if (!(control is DynamicControlBase) || control.Controls.Count <= 0 || !(control.Controls[0] is HtmlGenericControl)) continue;

                            var controlInPage = control as DynamicControlBase;
                            controlInPage.ControlInfo = moduleInPage;
                            controlInPage.IsDesignMode = true;

                            //var controlContainer = controlInPage.Controls[0] as HtmlGenericControl;

                            //if (null == controlContainer) continue;

                            //var moduleContainerClassName = controlContainer.Attributes["class"];
                            //moduleContainerClassName = moduleContainerClassName + " " +
                            //                           ModuleWapperCssClassName;
                            //controlContainer.Attributes["class"] = moduleContainerClassName;

                            //controlContainer.Attributes.Add("moduleid", moduleInPage.Module.Id.ToString());
                            //controlContainer.Attributes.Add("placeholdername", moduleInPage.PlaceHolderName);
                            //controlContainer.Attributes.Add("moduleinpageid", moduleInPage.Id.ToString());
                            //// -----------------------

                            //// Header để config module
                            //var skinData = moduleInPage.Module.ModuleSkin.Aggregate("",
                            //                                                        (current, skin) =>
                            //                                                        current +
                            //                                                        string.Format(
                            //                                                            HtmlModuleSkinItem,
                            //                                                            moduleInPage.Id,
                            //                                                            skin.SkinSrc,
                            //                                                            skin.SkinName));
                            //if (!string.IsNullOrEmpty(skinData))
                            //{
                            //    skinData = "<li>Chọn skin: </li>" + skinData +
                            //               "<li-----------------------------</li>";
                            //}
                            //var configHeader = string.Format(ConfigHeaderFormat,
                            //                                 moduleInPage.Module.ModuleName,
                            //                                 skinData, moduleInPage.Id);
                            //// Đặt header vào control container
                            //controlContainer.Controls.Add(new LiteralControl(configHeader));

                            // Đặt control container (thẻ li) vào placeholder (thẻ ul)
                            placeHolder.Controls.Add(controlInPage);
                        }
                    }
                }
                else
                {
                    LoadControlIntoPlaceHolderInAdminMode(pageControl, listModuleInPage);   
                }
            }
        }

        private void LoadControlIntoPlaceHolderInFrontEndMode(Control currentSearchControl, List<FullModuleInPageWithConfigEntity> listModuleInPage)
        {
            foreach (Control pageControl in currentSearchControl.Controls)
            {
                if (pageControl is HtmlGenericControl)
                {
                    var placeHolder = pageControl as HtmlGenericControl;
                    var placeHolderName = placeHolder.Attributes["placeholdername"];
                    if (!string.IsNullOrEmpty(placeHolderName))
                    {
                        foreach (var moduleInPage in listModuleInPage)
                        {
                            if (moduleInPage.PlaceHolderName.Equals(placeHolderName,
                                                                    StringComparison.CurrentCultureIgnoreCase))
                            {
                                var control = LoadControl(moduleInPage.SkinSrc);

                                if (control is DynamicControlBase && control.Controls.Count > 0 && control.Controls[0] is HtmlGenericControl)
                                {
                                    var controlInPage = control as DynamicControlBase;
                                    controlInPage.ControlInfo = moduleInPage;
                                    controlInPage.IsDesignMode = false;

                                    placeHolder.Controls.Add(controlInPage);
                                }
                            }
                        }
                    }
                }
                else
                {
                    LoadControlIntoPlaceHolderInFrontEndMode(pageControl, listModuleInPage);
                }
            }
        }

        //public abstract void Page_Load(object sender, EventArgs e);
    }
}
